home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Source / wind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-23  |  19.9 KB  |  814 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     wind.c
  4.  
  5.     This module handles the commands in the Windows menu. It also contains
  6.     a few general purpose window management functions.
  7.     
  8.     Copyright © 1994-1995, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <Icons.h>
  13. #include <stdio.h>
  14.  
  15. #include "glob.h"
  16. #include "full.h"
  17. #include "menus.h"
  18. #include "newswatcher.h"
  19. #include "wind.h"
  20. #include "dialog.h"
  21. #include "drawutil.h"
  22. #include "windutil.h"
  23. #include "memutil.h"
  24. #include "strutil.h"
  25. #include "header.h"
  26. #include "iconutil.h"
  27. #include "resutil.h"
  28. #include "fileutil.h"
  29. #include "help.h"
  30.  
  31.  
  32.  
  33. #define kOpenPadlockID                210
  34. #define kClosedPadlockID            211
  35.  
  36.  
  37.  
  38. /*----------------------------------------------------------------------------
  39.     DoCycleWindows 
  40.     
  41.     Handle the "Cycle Windows" command.
  42.     
  43.     Entry:    wind = pointer to window.
  44. ----------------------------------------------------------------------------*/
  45.  
  46. void DoCycleWindows (WindowPtr wind)
  47. {
  48.     SendBehind(wind, nil);
  49. }
  50.  
  51.  
  52.  
  53. /*----------------------------------------------------------------------------
  54.     DoZoomWindow 
  55.     
  56.     Handle the "Zoom Window" command.
  57.             
  58.     Entry:    wind = pointer to window.
  59.     
  60.     Exit:    function result = error code.
  61. ----------------------------------------------------------------------------*/
  62.  
  63. OSErr DoZoomWindow (WindowPtr wind)
  64. {
  65.     WStateData **wState;
  66.     Rect r;
  67.     OSErr err = noErr;
  68.  
  69.     wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  70.     r = (**wState).stdState;
  71.     if (WindRectEqualRect(wind, &r)) {
  72.         err = DoZoom(wind, inZoomIn);
  73.     } else {
  74.         err = DoZoom(wind, inZoomOut);
  75.     }
  76.     return err;
  77. }
  78.  
  79.  
  80.  
  81. /*----------------------------------------------------------------------------
  82.     DoShowHideFullGroupList 
  83.     
  84.     Handle the "Show/Hide Full Group List" command.
  85.     
  86.     Exit:    function result = error code.
  87. ----------------------------------------------------------------------------*/
  88.  
  89. OSErr DoShowHideFullGroupList (void)
  90. {
  91.     OSErr err = noErr;
  92.  
  93.     if (((WindowPeek)gFullGroupWindow)->visible) {
  94.         HideWindow(gFullGroupWindow);
  95.         SetWindowsMenuShowHideFullGroupList(true);
  96.     } else {
  97.         if (gMustDoZoomOnShowFullGroupList) {
  98.             err = DoZoom(gFullGroupWindow, inZoomOut);
  99.             if (err != noErr) return err;
  100.         }
  101.         gMustDoZoomOnShowFullGroupList = false;
  102.         MyShowWindow(gFullGroupWindow);
  103.         SetWindowsMenuShowHideFullGroupList(false);
  104.         MySelectWindow(gFullGroupWindow);
  105.     }
  106.     return noErr;
  107. }
  108.  
  109.  
  110.  
  111. /*----------------------------------------------------------------------------
  112.     RebuildWindowsMenu
  113.     
  114.     Rebuild the list of open windows in the Windows menu.
  115. ----------------------------------------------------------------------------*/
  116.  
  117. void RebuildWindowsMenu (void)
  118. {
  119.     WindowPtr wind;
  120.     MenuHandle menu;
  121.     Str255 title;
  122.     Str255 menuStr;
  123.     short item, len, numItems, numDel;
  124.     TWindowKind kind;
  125.     TWindow **info;
  126.     Handle fullText;
  127.     CStr255 from;
  128.     
  129.     menu = GetMenuHandle(kWindMenu);
  130.     numItems = CountMItems(menu);
  131.     numDel = numItems - kFirstOpenWindItem + 1;
  132.     while (numDel--) DeleteMenuItem(menu, kFirstOpenWindItem);
  133.     item = kFirstOpenWindItem;
  134.     for (wind = FrontWindow(); 
  135.         wind != nil; 
  136.         wind = (WindowPtr)((WindowPeek)wind)->nextWindow) 
  137.     {
  138.         kind = GetMyWindowKind(wind);
  139.         if (kind != kNotOurWind && ((WindowPeek)wind)->visible) {
  140.             GetWTitle(wind, title);
  141.             len = *title;
  142.             if (len > 0 && title[1] == checkMark) {
  143.                 len--;
  144.                 BlockMoveData(title+2, title+1, len);
  145.                 *title = len;
  146.             }
  147.             if (kind == kArticle) {
  148.                 info = (TWindow**)GetWRefCon(wind);
  149.                 fullText = (**info).fullText;
  150.                 if (FindHeaderCString(fullText, "From", from, sizeof(from))) {
  151.                     FormatAuthorName(from);
  152.                     p2cstr(title);
  153.                     sprintf((char*)menuStr, "%.25s, %.200s", from, (char*)title);
  154.                     c2pstr((char*)menuStr);
  155.                 } else {
  156.                     CopyPascalString(menuStr, title);
  157.                 }
  158.             } else {
  159.                 CopyPascalString(menuStr, title);
  160.             }
  161.             len = *menuStr;
  162.             if (len > 200) {
  163.                 len = 200;
  164.                 *menuStr = len;
  165.             }
  166.             if (len > 0) {
  167.                 if (menuStr[1] == '-') {
  168.                     if (len < 255) len++;
  169.                     BlockMoveData(menuStr+1, menuStr+2, len-1);
  170.                     menuStr[1] = ' ';
  171.                     *menuStr = len;
  172.                 }
  173.             } else {
  174.                 *menuStr = 1;
  175.                 menuStr[1] = 'x';
  176.             }
  177.             AppendMenu(menu, "\px");
  178.             SetMenuItemText(menu, item, menuStr);
  179.             if (wind == FrontWindow()) CheckItem(menu, item, true);
  180.             item++;
  181.         }
  182.     }
  183. }
  184.  
  185.  
  186.  
  187. /*----------------------------------------------------------------------------
  188.     SelectWindMenu 
  189.     
  190.     Handle a window selection command in the Windows menu.
  191.             
  192.     Entry:    item = item number of menu command.
  193. ----------------------------------------------------------------------------*/
  194.  
  195. void SelectWindMenu (short item)
  196. {
  197.     WindowPtr wind;
  198.  
  199.     item -= kFirstOpenWindItem;
  200.     for (wind = FrontWindow();
  201.         wind != nil;
  202.         wind = (WindowPtr)((WindowPeek)wind)->nextWindow)
  203.     {
  204.         if (GetMyWindowKind(wind) != kNotOurWind && ((WindowPeek)wind)->visible) {
  205.             if (item <= 0) {
  206.                 MySelectWindow(wind);
  207.                 return;
  208.             } else {
  209.                 item--;
  210.             }
  211.         }
  212.     }
  213. }
  214.  
  215.  
  216.  
  217. /*----------------------------------------------------------------------------
  218.     GetMyWindowKind 
  219.     
  220.     Get the window kind.
  221.             
  222.     Entry:    wind = pointer to window.
  223.     
  224.     Exit:    function result = window kind.
  225. ----------------------------------------------------------------------------*/
  226.  
  227. TWindowKind GetMyWindowKind (WindowPtr wind)
  228. {
  229.     TWindow **info;
  230.     short windowKind;
  231.  
  232.     if (wind == nil) return kNotOurWind;
  233.     windowKind = ((WindowPeek)wind)->windowKind;
  234.     if (windowKind < 0) return kNotOurWind;
  235.     if (windowKind == dialogKind && wind != gMyCurDialog) return kNotOurWind;
  236.     info = (TWindow**)GetWRefCon(wind);
  237.     if (info == nil) return kNotOurWind;
  238.     return (**info).kind;
  239. }
  240.  
  241.  
  242.  
  243. /*----------------------------------------------------------------------------
  244.     CreateNewWindow
  245.     
  246.     Create a new window.
  247.     
  248.     Entry:    kind = window kind.
  249.             title = window title.
  250.             font = window font.
  251.             size = window font size.
  252.     
  253.     Exit:    function result = error code.
  254.             *theWindow = pointer to new window.
  255. ----------------------------------------------------------------------------*/
  256.  
  257. OSErr CreateNewWindow (TWindowKind kind, StringPtr title, 
  258.     StringPtr font, short size, WindowPtr *theWindow)
  259. {
  260.     WindowPtr wind = nil, prev, next, behind;
  261.     TWindow **info;
  262.     Rect bounds;
  263.     OSErr err = noErr;
  264.     short fontNum, wDefProcID;
  265.     GrafPtr port;
  266.     
  267.     GetPort(&port);
  268.         
  269.     SetRect(&bounds, 0, 0, 100, 100);
  270.     
  271.     /* Compute the window layer position. If the frontmost window belonging
  272.        to NewsWatcher is the status window, create the new window behind
  273.        the status window. Otherwise, create the new window in front of the
  274.        frontmost window belonging to NewsWatcher. */
  275.     
  276.     prev = nil;
  277.     next = FrontWindow();
  278.     while (next != nil && ((WindowPeek)next)->windowKind < 0) {
  279.         prev = next;
  280.         next = (WindowPtr)((WindowPeek)next)->nextWindow;
  281.     }
  282.     if (GetMyWindowKind(next) == kStatus) {
  283.         behind = next;
  284.     } else if (prev == nil) {
  285.         behind = (WindowPtr)-1;
  286.     } else {
  287.         behind = prev;
  288.     }
  289.     
  290.     wDefProcID = kind == kStatus ? movableDBoxProc : zoomDocProc;
  291.     err = MyNewWindow(&bounds, title, false, wDefProcID, behind, true, 0, &wind);
  292.     if (err != noErr) goto exit;
  293.     SetPort(wind);
  294.     
  295.     GetFontNumber(font, &fontNum);
  296.     TextFont(fontNum);
  297.     TextSize(size);
  298.  
  299.     err = MyNewHandle(sizeof(TWindow), &info);
  300.     if (err != noErr) goto exit;        
  301.     (**info).kind = kind;
  302.     SetWRefCon(wind, (long)info);
  303.     
  304.     *theWindow = wind;
  305.     SetPort(port);
  306.     return noErr;
  307.  
  308. exit:
  309.  
  310.     MyDisposeWindow(wind);
  311.     SetPort(port);
  312.     return err;
  313. }
  314.  
  315.  
  316.  
  317. /*----------------------------------------------------------------------------
  318.     PositionNewWindow
  319.     
  320.     Position a new window.
  321.     
  322.     Entry:    wind = pointer to window.
  323.             width = window width.
  324.             height = window height.
  325. ----------------------------------------------------------------------------*/
  326.  
  327. void PositionNewWindow (WindowPtr wind, short width, short height)
  328. {
  329.     WindowPtr theWind;
  330.     WindowPeek theWindPeek;
  331.     TWindowKind kind;
  332.     
  333.     for (theWind = FrontWindow(); 
  334.         theWind != nil; 
  335.         theWind = (WindowPtr)((WindowPeek)theWind)->nextWindow) 
  336.     {
  337.         theWindPeek = (WindowPeek)theWind;
  338.         if (theWindPeek->windowKind < 0) continue;
  339.         if (theWind == wind) continue;
  340.         if (!theWindPeek->visible) continue;
  341.         kind = GetMyWindowKind(theWind);
  342.         if (kind == kStatus || kind == kNotOurWind || kind == kDummy) continue;
  343.         if (gStartingUp && theWind == gFullGroupWindow) continue;
  344.         break;
  345.     }
  346.  
  347.     StaggerWindow(wind, width, height, theWind, gPrefs.dontCoverFinderIcons);
  348. }
  349.  
  350.  
  351.  
  352. /*----------------------------------------------------------------------------
  353.     MyShowWindow
  354.     
  355.     Show a window.
  356.     
  357.     Entry:    wind = pointer to window.
  358. ----------------------------------------------------------------------------*/
  359.  
  360. void MyShowWindow (WindowPtr wind)
  361. {
  362.     EventRecord ev;
  363.     
  364.     if (gInBackground) HandleActivate(wind, false);
  365.     ShowWindow(wind);
  366.     while (WaitNextEvent(activMask | osMask, &ev, 0, nil))
  367.         HandleEvent(&ev);
  368. }
  369.  
  370.  
  371.  
  372. /*----------------------------------------------------------------------------
  373.     SaveWindPos
  374.     
  375.     Save a window position.
  376.     
  377.     Entry:    wind = pointer to window.
  378.     
  379.     Exit:    *pos = saved position.
  380. ----------------------------------------------------------------------------*/
  381.  
  382. void SaveWindPos (WindowPtr wind, TSavedWindPos *pos)
  383. {
  384.     TWindow **info;
  385.     GrafPtr port;
  386.     WStateData **wState;
  387.     Rect r, stdState;
  388.     
  389.     info = (TWindow**)GetWRefCon(wind);
  390.     if ((**info).windPosValid) {
  391.         GetPort(&port);
  392.         SetPort(wind);
  393.         pos->valid = true;
  394.         pos->oldFormat = false;
  395.         r = wind->portRect;
  396.         LocalToGlobalRect(&r);
  397.         wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  398.         stdState = (**wState).stdState;
  399.         pos->zoomed = EqualRect(&stdState, &r);
  400.         if (pos->zoomed) {
  401.             pos->userState = (**wState).userState;
  402.         } else {
  403.             pos->userState = r;
  404.         }
  405.         SetPort(port);
  406.     } else {
  407.         pos->valid = false;
  408.     }
  409. }
  410.  
  411.  
  412.  
  413. /*----------------------------------------------------------------------------
  414.     RestoreWindPos
  415.     
  416.     Restore a window position.
  417.     
  418.     Entry:    wind = pointer to window.
  419.             pos = pointer to saved position.
  420.             
  421.     Exit:    *needsZooming = true if window should be zoomed.
  422. ----------------------------------------------------------------------------*/
  423.  
  424. void RestoreWindPos (WindowPtr wind, TSavedWindPos *pos, Boolean *needsZooming)
  425. {
  426.     TWindow **info;
  427.     GrafPtr port;
  428.     WStateData **wState;
  429.     Rect r;
  430.     Boolean mainScreen, onOneScreen, useDefaultPos;
  431.     short width, height;
  432.     
  433.     GetPort(&port);
  434.     SetPort(wind);
  435.     info = (TWindow**)GetWRefCon(wind);
  436.     
  437.     useDefaultPos = !pos->valid;
  438.     
  439.     if (!useDefaultPos) {
  440.         MoveWindow(wind, pos->userState.left, pos->userState.top, false);
  441.         if (pos->oldFormat) {
  442.             *needsZooming = true;
  443.         } else {
  444.             width = pos->userState.right - pos->userState.left;
  445.             height = pos->userState.bottom - pos->userState.top;
  446.             SizeWindow(wind, width, height, false);
  447.             *needsZooming = pos->zoomed;
  448.         }
  449.         if (!WindOnScreen(wind)) useDefaultPos = true;
  450.      }
  451.     
  452.     (**info).windPosValid = !useDefaultPos; 
  453.     
  454.     if (useDefaultPos) {
  455.         if ((**info).kind == kGroup && (**info).groupKind == kFullGroup) {
  456.             MoveWindow(wind, 10, GetMBarHeight() + 30, false);
  457.             GetDominantScreen(gFullGroupWindow, &r, &mainScreen, &onOneScreen);
  458.             MoveWindow(wind, r.right - wind->portRect.right - 64,
  459.                 r.top + GetMBarHeight() + 30, false);
  460.         } else {
  461.             PositionNewWindow(wind, wind->portRect.right, wind->portRect.bottom);
  462.         }
  463.         *needsZooming = true;
  464.     }
  465.         
  466.     wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  467.     r = wind->portRect;
  468.     LocalToGlobalRect(&r);
  469.     (**wState).userState = r;
  470.     
  471.     SetPort(port);
  472. }
  473.  
  474.  
  475.  
  476. /*----------------------------------------------------------------------------
  477.     SaveWindPosAsResource
  478.     
  479.     Save a window position as a 'WPOS' id=128 resource on the current
  480.     resource file.
  481.     
  482.     Entry:    wind = pointer to window.
  483.     
  484.     Exit:    function result = error code.
  485. ----------------------------------------------------------------------------*/
  486.  
  487. OSErr SaveWindPosAsResource (WindowPtr wind)
  488. {
  489.     TSavedWindPos pos;
  490.     Handle h = nil;
  491.     OSErr err = noErr;
  492.     TWindow **info;
  493.     
  494.     SaveWindPos(wind, &pos);
  495.     err = MyPtrToHand(&pos, &h, sizeof(pos));
  496.     if (err != noErr) goto exit;
  497.     err = MyReplaceResource(h, 'WPOS', 128, "\p");
  498.     if (err != noErr) goto exit;
  499.     info = (TWindow**)GetWRefCon(wind);
  500.     (**info).movedSinceLastSave = false;
  501.     return noErr;
  502.     
  503. exit:
  504.  
  505.     MyDisposeHandle(h);
  506.     return err;
  507. }
  508.  
  509.  
  510.  
  511. /*----------------------------------------------------------------------------
  512.     SaveWindPosToFile
  513.     
  514.     If necessary, save just a changed window position to a document file,
  515.     without changing the window's last mod date.
  516.     
  517.     Entry:    wind = pointer to window.
  518.     
  519.     Exit:    function result = error code.
  520. ----------------------------------------------------------------------------*/
  521.  
  522. OSErr SaveWindPosToFile (WindowPtr wind)
  523. {
  524.     TWindow **info;
  525.     AliasHandle alias;
  526.     FSSpec fSpec;
  527.     OSErr err = noErr;
  528.     Boolean wasChanged;
  529.     short refNum = 0;
  530.     unsigned long lastModDateTime;
  531.     FInfo fInfo;
  532.     
  533.     /* Note that errors are ignored. This is not a critical operation,
  534.        and we don't want to interfere with closing a window just because
  535.        something fails here. */
  536.     
  537.     info = (TWindow**)GetWRefCon(wind);
  538.     alias = (**info).alias;
  539.     if (alias == nil || !(**info).movedSinceLastSave) return noErr;
  540.     err = ResolveAlias(nil, alias, &fSpec, &wasChanged);
  541.     if (err != noErr) return noErr;
  542.     err = FSpGetFInfo(&fSpec, &fInfo);
  543.     if (err != noErr) return noErr;
  544.     if (fInfo.fdCreator != kNewsWatcherSignature) return noErr;
  545.     err = GetLastModDateTime(&fSpec, &lastModDateTime);
  546.     if (err != noErr) return noErr;
  547.     err = MyFSpOpenResFile(&fSpec, fsRdWrPerm, &refNum);
  548.     if (err != noErr) return noErr;
  549.     err = SaveWindPosAsResource(wind);
  550.     if (err != noErr) goto exit;
  551.     MyCloseResFile(refNum);
  552.     err = SetLastModDateTime(&fSpec, lastModDateTime);
  553.     return noErr;
  554.     
  555. exit:
  556.  
  557.     if (refNum != 0) MyCloseResFile(refNum);
  558.     return noErr;
  559. }
  560.  
  561.  
  562.  
  563. /*----------------------------------------------------------------------------
  564.     RestoreLockedWindowPosition
  565.     
  566.     Restore a locked window position.
  567.     
  568.     Entry:    wind = pointer to subject, article, or message window.
  569.             width = unlocked width of window.
  570.             height = unlocked height of window.
  571.             windPosLocked = true if this kind of window has a saved
  572.                 locked position.
  573.             *windLocn = saved locked window position.
  574.             
  575.     If this kind of window has a saved locked window position, and if
  576.     no other window of this kind is already open, the saved locked window
  577.     position is restored. Otherwise, the default window postion is set.
  578. ----------------------------------------------------------------------------*/
  579.  
  580. void RestoreLockedWindowPosition (WindowPtr wind, short width, short height,
  581.     Boolean windPosLocked, Rect *windLocn)
  582. {
  583.     TWindow **info;
  584.     TWindowKind kind;
  585.     WindowPtr w;
  586.     GrafPtr port;
  587.     WStateData **wState;
  588.     Rect r;
  589.     
  590.     GetPort(&port);
  591.     SetPort(wind);
  592.  
  593.     info = (TWindow**)GetWRefCon(wind);
  594.     kind = (**info).kind;
  595.     
  596.     if (windPosLocked) {
  597.         for (w = FrontWindow(); w != nil; w = (WindowPtr)((WindowPeek)w)->nextWindow) {
  598.             if (kind == GetMyWindowKind(w) && w != wind) {
  599.                 windPosLocked = false;
  600.                 break;
  601.             }
  602.         }
  603.     }
  604.     
  605.     if (windPosLocked) {
  606.         MoveWindow(wind, windLocn->left, windLocn->top, false);
  607.         SizeWindow(wind, windLocn->right - windLocn->left, 
  608.             windLocn->bottom - windLocn->top, false);
  609.         if (WindOnScreen(wind)) {
  610.             wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  611.             r = wind->portRect;
  612.             LocalToGlobalRect(&r);
  613.             (**wState).userState = r;
  614.         } else {
  615.             windPosLocked = false;
  616.         }
  617.     }
  618.     
  619.     if (!windPosLocked) {
  620.         PositionNewWindow(wind, width, height);
  621.     }
  622.     
  623.     (**info).windPosLocked = windPosLocked;
  624.     
  625.     SetPort(port);
  626. }
  627.  
  628.  
  629.  
  630. /*----------------------------------------------------------------------------
  631.     DrawPadlockIcon
  632.     
  633.     Draw the padlock icon in a window.
  634.     
  635.     Entry:    wind = pointer to subject, article, or message window.
  636. ----------------------------------------------------------------------------*/
  637.  
  638. void DrawPadlockIcon (WindowPtr wind)
  639. {
  640.     TWindow **info;
  641.     short windHeight;
  642.     Rect padlockRect;
  643.  
  644.     info = (TWindow**)GetWRefCon(wind);
  645.     windHeight = wind->portRect.bottom;
  646.     SetRect(&padlockRect, 1, windHeight-17, 17, windHeight-1); 
  647.     PlotIconID(&padlockRect, 0, ttNone, 
  648.         (**info).windPosLocked ? kClosedPadlockID : kOpenPadlockID);
  649. }
  650.  
  651.  
  652.  
  653. /*----------------------------------------------------------------------------
  654.     HandlePadlockClick
  655.     
  656.     Check for and handle a click on a padlock icon.
  657.     
  658.     Entry:    wind = pointer to subject, article, or message window.
  659.             where = location of mouse down event, in local coords.
  660.             windPosLocked = pointer to windPosLocked preference for
  661.                 this kind of window.
  662.             windLocn = pointer to saved locked window position for
  663.                 this kind of window.
  664.                 
  665.     Exit:    function result = true if padlock clicked.
  666. ----------------------------------------------------------------------------*/
  667.  
  668. Boolean HandlePadlockClick (WindowPtr wind, Point where, 
  669.     Boolean *windPosLocked, Rect *windLocn)
  670. {
  671.     TWindow **info;
  672.     short windHeight, iconID;
  673.     Rect padlockRect, hotRect;
  674.     GrafPtr port;
  675.     WindowPtr w;
  676.     TWindowKind kind;
  677.  
  678.     GetPort(&port);
  679.     SetPort(wind);
  680.     
  681.     info = (TWindow**)GetWRefCon(wind);
  682.     windHeight = wind->portRect.bottom;
  683.     SetRect(&padlockRect, 0, windHeight-16, 16, windHeight); 
  684.     hotRect = padlockRect;
  685.     hotRect.top += 2;
  686.     hotRect.right -= 1;
  687.     iconID = (**info).windPosLocked ? kClosedPadlockID : kOpenPadlockID;
  688.     
  689.     if (!TrackIconClick(where, &padlockRect, &hotRect, iconID)) {
  690.         SetPort(port);
  691.         return false;
  692.     }
  693.     
  694.     SetRect(&padlockRect, 0, windHeight - 13, 13, windHeight);
  695.     
  696.     (**info).windPosLocked = *windPosLocked = !(**info).windPosLocked;
  697.     InvalRect(&padlockRect);
  698.     if (*windPosLocked) {
  699.         *windLocn = wind->portRect;
  700.         LocalToGlobalRect(windLocn);
  701.         SetPort(port);
  702.         kind = (**info).kind;
  703.         for (w = FrontWindow(); w != nil; w = (WindowPtr)((WindowPeek)w)->nextWindow) {
  704.             if (kind == GetMyWindowKind(w) && w != wind) {
  705.                 info = (TWindow**)GetWRefCon(w);
  706.                 if ((**info).windPosLocked) {
  707.                     (**info).windPosLocked = false;
  708.                     SetPort(w);
  709.                     windHeight = w->portRect.bottom;
  710.                     SetRect(&padlockRect, 0, windHeight - 13, 13, windHeight);
  711.                     InvalRect(&padlockRect);
  712.                 }
  713.             }
  714.         }
  715.     }
  716.     KillBalloon();
  717.     SetPort(port);
  718.     return true;
  719. }
  720.  
  721.  
  722.  
  723. /*----------------------------------------------------------------------------
  724.     RecordNewLockedWindowPosition
  725.     
  726.     Record the new locked window position after a locked window is resized.
  727.     
  728.     Entry:    wind = pointer to subject, article, or message window.
  729.             windLocn = pointer to saved locked window position for
  730.                 this kind of window.
  731.                 
  732.     Exit:    *windLocn = new locked window position.
  733. ----------------------------------------------------------------------------*/
  734.  
  735. void RecordNewLockedWindowPosition (WindowPtr wind, Rect *windLocn)
  736. {
  737.     TWindow **info;
  738.     GrafPtr port;
  739.     
  740.     info = (TWindow**)GetWRefCon(wind);
  741.     if (!(**info).windPosLocked) return;
  742.     *windLocn = wind->portRect;
  743.     GetPort(&port);
  744.     SetPort(wind);
  745.     LocalToGlobalRect(windLocn);
  746.     SetPort(port);
  747. }
  748.  
  749.  
  750.  
  751. /*----------------------------------------------------------------------------
  752.     MySelectWindow
  753.     
  754.     Move a window to the front, or just behind the Status window if the
  755.     Status window is open.
  756.     
  757.     Entry:    wind = pointer to window.
  758. ----------------------------------------------------------------------------*/
  759.  
  760. void MySelectWindow (WindowPtr wind)
  761. {
  762.     WindowPtr front;
  763.     WindowRef wRef;
  764.  
  765.     front = MyFrontWindow();
  766.     if (GetMyWindowKind(front) == kStatus) {
  767.         wRef = (WindowRef)wind;
  768.         PaintOne(wRef, ((WindowPeek)wRef)->strucRgn);
  769.         CalcVis(wRef);
  770.         SendBehind(wind, front);
  771.     } else {
  772.         SelectWindow(wind);
  773.     }
  774. }
  775.  
  776.  
  777.  
  778. /*----------------------------------------------------------------------------
  779.     AdjustWindowTitlesOnResume
  780.     
  781.     Adjust the titles of all open windows which correspond to saved files
  782.     on a resume event, in case the user changed the file names.
  783. ----------------------------------------------------------------------------*/
  784.  
  785. void AdjustWindowTitlesOnResume (void)
  786. {
  787.     WindowPtr wind;
  788.     TWindowKind kind;
  789.     TWindow **info;
  790.     FSSpec fSpec;
  791.     Boolean wasChanged;
  792.     OSErr err = noErr;
  793.     Str255 title;
  794.  
  795.     for (wind = FrontWindow(); 
  796.         wind != nil; 
  797.         wind = (WindowPtr)((WindowPeek)wind)->nextWindow) 
  798.     {
  799.         kind = GetMyWindowKind(wind);
  800.         if (kind != kGroup && kind != kMessage) continue;
  801.         info = (TWindow**)GetWRefCon(wind);
  802.         if ((**info).alias == nil) continue;
  803.         err = ResolveAlias(nil, (**info).alias, &fSpec, &wasChanged);
  804.         if (err == noErr) {
  805.             GetWTitle(wind, title);
  806.             if (EqualString(title, fSpec.name, false, true)) continue;
  807.             SetWTitle(wind, fSpec.name);
  808.         } else {
  809.             MyDisposeHandle((**info).alias);
  810.             (**info).alias = nil;
  811.             (**info).changed = true;
  812.         }
  813.     }
  814. }